﻿/*********************************************************************************************************************
VanguardDocumentation, Procedure SetBaseEntity

© 2014 Erik Ackerholm

This file is part of SqlVanguard.

SqlVanguard is free software: you can redistribute it and/or modify it under the terms of the GNU General Public 
License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later 
version.

SqlVanguard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with SqlVanguard. If not, see 
<http://www.gnu.org/licenses/>.
*********************************************************************************************************************/

if
	not exists (
		select *
		from sys.schemas as s
			inner join sys.objects as o on (s.schema_id = o.schema_id)
		where s.name = 'VanguardDocumentation' and o.[type] = 'P'
			and o.name = 'SetBaseEntity'
	)
begin
	declare @SqlCommand as nvarchar(max);
	set @SqlCommand = '
		create procedure VanguardDocumentation.SetBaseEntity
		as raiserror (''Procedure SetBaseEntity is not implemented yet!'', 11, 1);
	';
	execute (@SqlCommand);
end;
GO

alter procedure VanguardDocumentation.SetBaseEntity
	/*****************************************************************************************************************
	Stores a base name to which more parts may be added.

	If you want to describe a table and its columns, you may call
		VanguardDocumentation.SetBaseEntity 'MySchema.MyTable';
		VanguardDocumentation.SetDescription null, 'Describes my table';
		VanguardDocumentation.SetDescription '.FirstCol', 'Stores some data';
		VanguardDocumentation.SetDescription '.SecondCol', 'Yada yada';
		...
	*****************************************************************************************************************/
	
	@EntityName                 nvarchar(512)
		/* Dot-separated name of entity. No checking will be done to see if the name exists or not. */
	
	with execute as owner
as
begin
	
	set nocount on;
	set xact_abort on;
	set lock_timeout 3000;
	set transaction isolation level read committed;
	
	declare @EntityNameNotNull as nvarchar(512);
	
	declare @ErrorNo as integer;
	declare @ErrorMsg as nvarchar(1536);
	declare @ErrorLine as integer;
	declare @ErrorState as integer;
	
	begin try;
		
		-- The name must not be null when stored in XML. Creates a special variable which uses empty string as null.
		set @EntityNameNotNull = coalesce(@EntityName, '');
		
		-- Add empty variables (default) if none exists.
		-- Transaction between check (select) and insert not deemed necessary since noone else should write variables 
		-- for my own session
		if
			not exists (
				select * from VanguardDocumentation.SessionVariables
				where SessionID = @@spid
					and SessionStartTime = (select login_time from sys.dm_exec_sessions where session_id = @@spid)
			)
		begin
			insert into VanguardDocumentation.SessionVariables (SessionID, SessionStartTime)
			select session_id, login_time
			from sys.dm_exec_sessions
			where session_id = @@spid;
		end;
		
		-- Add variable BaseEntity if not exists in record.
		update VanguardDocumentation.SessionVariables
		set Variables.modify ('
			insert <BaseEntity Name=""/>
			as last into (/Variables)[1]
		')
		where SessionID = @@spid
			and SessionStartTime = (select login_time from sys.dm_exec_sessions where session_id = @@spid)
			and Variables.exist('/Variables/BaseEntity') = 0;
		
		-- Update the variable BaseEntity (which must now exist).
		update VanguardDocumentation.SessionVariables
		set Variables.modify ('
			replace value of (/Variables/BaseEntity/@Name)[1]
			with sql:variable("@EntityNameNotNull")
		')
		where SessionID = @@spid
			and SessionStartTime = (select login_time from sys.dm_exec_sessions where session_id = @@spid);
		
	end try
	begin catch;
		
		set @ErrorNo = error_number();
		set @ErrorMsg = left(error_message(), 1536);
		set @ErrorLine = error_line();
		set @ErrorState = error_state();
		
		raiserror (740900, 16, @ErrorState, 'SetBaseEntity', @ErrorNo, @ErrorLine, @ErrorMsg);
		
	end catch;
	
end;
GO

grant execute on VanguardDocumentation.SetBaseEntity to VanguardDocumentationReader;
grant execute on VanguardDocumentation.SetBaseEntity to VanguardDocumentationWriter;
GO




